from typing import Sequence

from fastapi import Request
from sqlalchemy import Select, ScalarResult, Row, RowMapping

from app.crud.crud_collection import collection_dao
from app.crud.crud_knowledge_base import knowledge_base_dao
from app.model import Conservation
from app.schema import CreateKnowledgeBaseParam, CreateCollectionParam
from app.schema.conservation_schema import (
    CreateConservationParam,
    UpdateConservationParam,
)
from common.exception import errors
from database.db_mysql import async_db_session
from app.crud.crud_conservation import conservation_dao


class ConservationService:
    @staticmethod
    async def add(*, request: Request, obj: CreateConservationParam) -> Conservation:
        async with async_db_session.begin() as db:
            # 关联的用户UUID和智能体UUID
            knowledge_base = await knowledge_base_dao.create(db=db, obj=CreateKnowledgeBaseParam(
                user_uuid=request.user.uuid,
                name=obj.name,
                description=obj.name,
                cover_image=obj.name,
                status=2
            ))

        async with async_db_session.begin() as db:
            # 关联的用户UUID和智能体UUID
            collection = await collection_dao.create(db=db, obj=CreateCollectionParam(
                knowledge_base_uuid=knowledge_base.uuid,
                name="聊天笔记",
                file_url="聊天笔记",
            ))

        async with async_db_session.begin() as db:
            obj.knowledge_base_uuid = knowledge_base.uuid
            obj.collection_uuid = collection.uuid
            obj.user_uuid = request.user.uuid
            # 创建会话
            new_conservation = await conservation_dao.create(db, obj)
            return new_conservation

    @staticmethod
    async def update(*, request: Request, conservation_uuid: str, obj: UpdateConservationParam) -> int:
        async with async_db_session.begin() as db:
            # 获取会话并检查权限
            conservation = await conservation_dao.get_by_uuid(db, conservation_uuid)
            if not conservation:
                raise errors.NotFoundError(msg="会话不存在")

            # 权限检查：如果不是超级管理员，且不是自己的会话，不能修改
            if not request.user.is_superuser and conservation.user_uuid != request.user.uuid:
                raise errors.ForbiddenError(msg="您没有权限修改该会话")

            # 更新会话
            count = await conservation_dao.update(db, conservation_uuid, obj)
            return count

    @staticmethod
    async def update_status(*, request: Request, conservation_uuid: str, status: bool) -> int:
        async with async_db_session.begin() as db:
            # 获取会话并检查权限
            conservation = await conservation_dao.get_by_uuid(db, conservation_uuid)
            if not conservation:
                raise errors.NotFoundError(msg="会话不存在")

            # 权限检查：如果不是超级管理员，且不是自己的会话，不能修改
            if not request.user.is_superuser and conservation.user_uuid != request.user.uuid:
                raise errors.ForbiddenError(msg="您没有权限修改该会话")

            # 更新会话状态
            count = await conservation_dao.set_status(db, conservation_uuid, status)
            return count

    @staticmethod
    async def delete(*, request: Request, conservation_uuid: str) -> int:
        async with async_db_session.begin() as db:
            # 获取会话并检查权限
            conservation = await conservation_dao.get_by_uuid(db, conservation_uuid)
            if not conservation:
                raise errors.NotFoundError(msg="会话不存在")

            # 权限检查：普通用户只能删除自己的会话
            if not request.user.is_superuser and conservation.user_uuid != request.user.uuid:
                raise errors.ForbiddenError(msg="您没有权限删除该会话")

            # 删除会话
            count = await conservation_dao.delete(db, conservation_uuid)
            return count

    @staticmethod
    async def get_conservation(*, request: Request, conservation_uuid: str) -> Conservation:
        async with async_db_session() as db:
            # 获取会话并检查权限
            conservation = await conservation_dao.get_by_uuid(db, conservation_uuid)
            if not conservation:
                raise errors.NotFoundError(msg="会话不存在")

            # 权限检查：如果不是超级管理员，且不是自己的会话，不能获取
            if not request.user.is_superuser and conservation.user_uuid != request.user.uuid:
                raise errors.ForbiddenError(msg="您没有权限查看该会话")

            return conservation

    @staticmethod
    async def get_select(*, user_uuid: str = None, name: str = None, agent_uuid: str = None, status: int = None) -> Select:
        return await conservation_dao.get_list(user_uuid=user_uuid, agent_uuid=agent_uuid, name=name)

    @staticmethod
    async def get_all(*, user_uuid: str = None, name: str = None, agent_uuid: str = None) -> Sequence[
        Row[Conservation] | RowMapping | Conservation]:
        async with async_db_session() as db:
            return await conservation_dao.get_all(db=db, user_uuid=user_uuid, agent_uuid=agent_uuid, name=name)

    @staticmethod
    async def get_with_relation(*, request: Request, conservation_uuid: str) -> Conservation:
        """
        获取会话与相关信息（智能体等）
        """
        async with async_db_session() as db:
            conservation = await conservation_dao.get_with_relation(db, conservation_uuid)
            if not conservation:
                raise errors.NotFoundError(msg="会话不存在")

            # 权限检查：如果不是超级管理员，且不是自己的会话，不能获取
            if not request.user.is_superuser and conservation.user_uuid != request.user.uuid:
                raise errors.ForbiddenError(msg="您没有权限查看该会话")

            return conservation


conservation_service = ConservationService()
